import React, { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
import {
  ShieldExclamationIcon,
  MagnifyingGlassIcon,
  BackspaceIcon,
  ChevronLeftIcon,
  ChevronDoubleLeftIcon,
  ChevronDoubleRightIcon,
  ChevronRightIcon,
  ArrowUpIcon,
  ArrowDownIcon,
  EyeIcon
} from '@heroicons/react/24/outline';
import { getSeverityClass, severityColors, statusColors } from '../lib/data/definitions-customer';
import { getVulnerabilityStatusColor, formatDate } from '../lib/utilities';
import { useDebounce } from '@uidotdev/usehooks';
import { SeverityBadge, VulnerabilityStatusBadge } from './status-badges';

interface Vulnerability {
  id: number;
  name: string;
  severity: string;
  status: string;
  discoveryDate?: string;
  cve?: string | null;
  cvssscore?: string | number;
  [key: string]: any; // Allow for additional properties
}

interface VulnerabilityDataTableProps {
  vulnerabilities: Vulnerability[];
  title?: string;
  showStats?: boolean;
  onVulnerabilityClick?: (vulnerability: Vulnerability) => void;
  initialSortField?: string;
  initialSortDirection?: 'asc' | 'desc';
}

export default function VulnerabilityDataTable({
  vulnerabilities,
  title = 'Identified Vulnerabilities',
  showStats = true,
  onVulnerabilityClick,
  initialSortField = 'severity',
  initialSortDirection = 'desc'
}: VulnerabilityDataTableProps) {
  const [searchQuery, setSearchQuery] = useState<string>('');
  const debouncedSearchQuery = useDebounce<string>(searchQuery, 300);
  const [filteredVulnerabilities, setFilteredVulnerabilities] = useState<Vulnerability[]>(vulnerabilities);
  const [currentPage, setCurrentPage] = useState<number>(1);
  const [rowsPerPage, setRowsPerPage] = useState<number>(10);
  const [totalRows, setTotalRows] = useState<number>(vulnerabilities.length);
  const [sortField, setSortField] = useState<string>(initialSortField); 
  const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>(initialSortDirection);

  // Filter vulnerabilities based on search query and sort
  useEffect(() => {
    let result = [...vulnerabilities];
    
    // Apply search filtering
    if (debouncedSearchQuery) {
      const lowerCaseQuery = debouncedSearchQuery.toLowerCase();
      result = result.filter(
        (vuln) => 
          vuln.name.toLowerCase().includes(lowerCaseQuery) ||
          (vuln.cve && vuln.cve.toLowerCase().includes(lowerCaseQuery)) ||
          vuln.severity.toLowerCase().includes(lowerCaseQuery) ||
          vuln.status.toLowerCase().includes(lowerCaseQuery) ||
          (vuln.description && vuln.description.toLowerCase().includes(lowerCaseQuery)) ||
          (vuln.discoveryDate && formatDate(vuln.discoveryDate).toLowerCase().includes(lowerCaseQuery))
      );
      setCurrentPage(1); // Reset to first page on new search
    }
      
    // Apply sorting
    const sortedResults = [...result].sort((a, b) => {
      const severityOrder: Record<string, number> = { 
        'Critical': 4, 
        'High': 3, 
        'Medium': 2, 
        'Low': 1, 
        'Informational': 0,
        'Info': 0 
      };
      
      let aValue: any, bValue: any;
        
      if (sortField === 'severity') {
        // Special handling for severity which is textual but has a specific order
        const aSeverity = (a.severity === 'None' ? 'Informational' : a.severity) as string;
        const bSeverity = (b.severity === 'None' ? 'Informational' : b.severity) as string;
        aValue = severityOrder[aSeverity] || 0;
        bValue = severityOrder[bSeverity] || 0;
      } else if (sortField === 'discoveryDate') {
        // Special handling for dates
        aValue = a.discoveryDate ? new Date(a.discoveryDate).getTime() : 0;
        bValue = b.discoveryDate ? new Date(b.discoveryDate).getTime() : 0;
      } else {
        // Default string comparison for other fields
        aValue = a[sortField] || '';
        bValue = b[sortField] || '';
      }
      
      // Determine sort direction
      let sortValue;
      if (typeof aValue === 'string' && typeof bValue === 'string') {
        sortValue = aValue.localeCompare(bValue);
      } else {
        sortValue = aValue > bValue ? 1 : aValue < bValue ? -1 : 0;
      }
      
      return sortDirection === 'asc' ? sortValue : -sortValue;
    });
    
    setFilteredVulnerabilities(sortedResults);
    setTotalRows(sortedResults.length);
  }, [debouncedSearchQuery, vulnerabilities, sortField, sortDirection]);

  // Calculate pagination
  const totalPages = Math.ceil(totalRows / rowsPerPage);
  const startIndex = (currentPage - 1) * rowsPerPage;
  const endIndex = Math.min(startIndex + rowsPerPage, totalRows);
  const paginatedVulnerabilities = filteredVulnerabilities.slice(startIndex, endIndex);

  // Handle page changes
  const goToPage = (page: number) => {
    setCurrentPage(Math.max(1, Math.min(page, totalPages)));
  };

  const goToFirstPage = () => goToPage(1);
  const goToPreviousPage = () => goToPage(currentPage - 1);
  const goToNextPage = () => goToPage(currentPage + 1);
  const goToLastPage = () => goToPage(totalPages);

  // Handle search query change
  const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    setSearchQuery(event.target.value);
  };

  const clearSearch = () => {
    setSearchQuery('');
  };
  
  // Handle rows per page change
  const handleRowsPerPageChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
    setRowsPerPage(Number(event.target.value));
    setCurrentPage(1); // Reset to first page when changing rows per page
  };
  
  // Handle sorting
  const handleSort = (field: string) => {
    if (sortField === field) {
      // Toggle direction if clicking the same field
      setSortDirection(sortDirection === 'asc' ? 'desc' : 'asc');
    } else {
      // Set new sort field and default to descending for severity, ascending for others
      setSortField(field);
      setSortDirection(field === 'severity' ? 'desc' : 'asc');
    }
  };

  // Render sort icon
  const renderSortIcon = (field: string) => {
    if (sortField === field) {
      return sortDirection === 'asc' ? 
        <ArrowUpIcon className="h-3 w-3 text-gray-500" /> : 
        <ArrowDownIcon className="h-3 w-3 text-gray-500" />;
    }
    return null;
  };
  
  return (
    <div className="bg-white dark:bg-gray-800 rounded-lg shadow overflow-hidden mb-8">
      {/* Header */}
      <div className="p-4 bg-gray-50 dark:bg-gray-700 flex justify-between items-center">
        <h3 className="font-semibold text-gray-900 dark:text-white flex items-center">
          <ShieldExclamationIcon className="w-5 h-5 mr-2" />
          {title}
        </h3>
        {showStats && (
          <div className="text-sm text-gray-500 dark:text-gray-400">
            Total: {totalRows} | Fixed: {filteredVulnerabilities.filter(v => v.status === 'Fixed' || v.status === 'Verified Fixed').length}
          </div>
        )}
      </div>

      {/* Search bar */}
      <div className="p-4 border-b border-gray-200 dark:border-gray-700">
        <div className="flex items-center bg-white dark:bg-gray-700 rounded-md border border-gray-300 dark:border-gray-600">
          <div className="pl-3 pr-1">
            <MagnifyingGlassIcon className="h-5 w-5 text-gray-400" />
          </div>
          <input
            type="text"
            placeholder="Search vulnerabilities..."
            value={searchQuery}
            onChange={handleSearchChange}
            className="flex-1 p-2 bg-transparent border-none focus:ring-0 focus:outline-none text-gray-900 dark:text-white"
          />
          {searchQuery && (
            <button
              onClick={clearSearch}
              className="p-2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200"
            >
              <BackspaceIcon className="h-5 w-5" />
            </button>
          )}
        </div>
      </div>
      
      {/* Table view */}
      <div className="overflow-x-auto">
        <table className="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
          <thead className="bg-gray-50 dark:bg-gray-700">
            <tr>
              <th scope="col" className="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
                <button 
                  className="flex items-center focus:outline-none"
                  onClick={() => handleSort('name')}
                >
                  Name
                  <span className="ml-1">{renderSortIcon('name')}</span>
                </button>
              </th>
              <th scope="col" className="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
                <button 
                  className="flex items-center focus:outline-none"
                  onClick={() => handleSort('discoveryDate')}
                >
                  Discovered Date
                  <span className="ml-1">{renderSortIcon('discoveryDate')}</span>
                </button>
              </th>
              <th scope="col" className="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
                <button 
                  className="flex items-center focus:outline-none"
                  onClick={() => handleSort('severity')}
                >
                  Severity
                  <span className="ml-1">{renderSortIcon('severity')}</span>
                </button>
              </th>              <th scope="col" className="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
                <button 
                  className="flex items-center focus:outline-none"
                  onClick={() => handleSort('status')}
                >
                  Status
                  <span className="ml-1">{renderSortIcon('status')}</span>
                </button>
              </th>
              <th scope="col" className="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
                Actions
              </th>
            </tr>
          </thead>
          <tbody className="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">            {paginatedVulnerabilities.length === 0 ? (
              <tr>
                <td colSpan={5} className="px-6 py-4 text-center text-gray-500 dark:text-gray-400">
                  {searchQuery ? 'No vulnerabilities match your search.' : 'No vulnerabilities have been identified yet.'}
                </td>
              </tr>
            ) : (
              paginatedVulnerabilities.map((vuln) => (
                <tr 
                  key={vuln.id} 
                  className={`hover:bg-gray-50 dark:hover:bg-gray-700/50 ${onVulnerabilityClick ? 'cursor-pointer' : ''}`}
                  onClick={onVulnerabilityClick ? () => onVulnerabilityClick(vuln) : undefined}
                >
                  <td className="px-4 py-4 whitespace-nowrap">
                    <div className="flex items-center">
                      <div>
                        <div className="text-sm font-medium text-gray-900 dark:text-white">{vuln.name}</div>
                        {vuln.cve && (
                          <div className="text-xs text-blue-600 dark:text-blue-400 mt-1">
                            {vuln.cve}
                          </div>
                        )}
                      </div>
                    </div>
                  </td>
                  <td className="px-4 py-4 whitespace-nowrap">
                    <div className="text-sm text-gray-500 dark:text-gray-400">
                      {formatDate(vuln.discoveryDate)}
                    </div>
                  </td>
                  <td className="px-4 py-4 whitespace-nowrap">
                    <SeverityBadge 
                      severity={vuln.severity === 'None' ? 'Informational' : vuln.severity} 
                    />
                  </td>                  <td className="px-4 py-4 whitespace-nowrap">
                    <VulnerabilityStatusBadge status={vuln.status} />
                  </td>                  <td className="px-4 py-4 whitespace-nowrap">
                    <Link
                      to={`/customer/project/vulnerability/view/${vuln.id}`}
                      className="inline-flex items-center px-3 py-1.5 border border-transparent text-xs font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
                      onClick={(e) => e.stopPropagation()} // Prevent row click handler from firing
                    >
                      <EyeIcon className="h-4 w-4 mr-1" />
                      View
                    </Link>
                  </td>
                </tr>
              ))
            )}
          </tbody>
        </table>
      </div>
      
      {/* Pagination controls */}
      {filteredVulnerabilities.length > 0 && (
        <div className="bg-gray-50 dark:bg-gray-700 px-4 py-3 flex items-center justify-between border-t border-gray-200 dark:border-gray-600">
          <div className="flex items-center">
            <span className="text-sm text-gray-700 dark:text-gray-300">
              Showing <span className="font-medium">{startIndex + 1}</span> to <span className="font-medium">{endIndex}</span> of{' '}
              <span className="font-medium">{totalRows}</span> vulnerabilities
            </span>
            <div className="ml-4">
              <select
                id="rowsPerPage"
                name="rowsPerPage"
                className="text-sm border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white rounded-md focus:border-blue-500"
                value={rowsPerPage}
                onChange={handleRowsPerPageChange}
              >
                <option value={5}>5 per page</option>
                <option value={10}>10 per page</option>
                <option value={25}>25 per page</option>
                <option value={50}>50 per page</option>
              </select>
            </div>
          </div>
          <div className="flex items-center space-x-2">
            <button
              onClick={goToFirstPage}
              disabled={currentPage === 1}
              className={`p-1 rounded-md ${
                currentPage === 1
                  ? 'text-gray-400 cursor-not-allowed'
                  : 'text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-600'
              }`}
            >
              <ChevronDoubleLeftIcon className="h-5 w-5" />
            </button>
            <button
              onClick={goToPreviousPage}
              disabled={currentPage === 1}
              className={`p-1 rounded-md ${
                currentPage === 1
                  ? 'text-gray-400 cursor-not-allowed'
                  : 'text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-600'
              }`}
            >
              <ChevronLeftIcon className="h-5 w-5" />
            </button>
            <span className="px-4 py-1 rounded-md bg-white dark:bg-gray-800 text-gray-700 dark:text-gray-300 border border-gray-300 dark:border-gray-600">
              {currentPage} / {totalPages}
            </span>
            <button
              onClick={goToNextPage}
              disabled={currentPage === totalPages}
              className={`p-1 rounded-md ${
                currentPage === totalPages
                  ? 'text-gray-400 cursor-not-allowed'
                  : 'text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-600'
              }`}
            >
              <ChevronRightIcon className="h-5 w-5" />
            </button>
            <button
              onClick={goToLastPage}
              disabled={currentPage === totalPages}
              className={`p-1 rounded-md ${
                currentPage === totalPages
                  ? 'text-gray-400 cursor-not-allowed'
                  : 'text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-600'
              }`}
            >
              <ChevronDoubleRightIcon className="h-5 w-5" />
            </button>
          </div>
        </div>
      )}
    </div>
  );
}
